package com.campus.counseling.service.impl;

import com.campus.counseling.entity.MentalHealthWarning;
import com.campus.counseling.model.mapper.MentalHealthWarningMapper;
import com.campus.counseling.service.LSTMAnalysisService;
import com.campus.counseling.service.MentalHealthWarningService;
import com.campus.counseling.service.ChatAnalysisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;

import com.campus.counseling.enums.WarningLevel;
import com.campus.counseling.entity.ChatAnalysis;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.nd4j.linalg.api.ndarray.INDArray;
import com.campus.counseling.service.DL4JModelService;

@Slf4j
@Service
@RequiredArgsConstructor
public class MentalHealthWarningServiceImpl implements MentalHealthWarningService {

    private final LSTMAnalysisService lstmAnalysisService;
    private final ChatAnalysisService chatAnalysisService;
    private final MentalHealthWarningMapper warningMapper;
    private final DL4JModelService dl4jModelService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MentalHealthWarning analyzeAndGenerateWarning(Long userId, List<String> texts) {
        try {
            // 1. 获取LSTM原始分数和最终融合分数
            INDArray features = dl4jModelService.extractFeatures(texts);
            INDArray predictions = dl4jModelService.predict(features);
            BigDecimal lstmScore = BigDecimal.valueOf(predictions.getDouble(0))
                .setScale(4, RoundingMode.HALF_UP);
            
            // 获取最终融合分数
            BigDecimal finalScore = lstmAnalysisService.analyzeChatContent(texts);
            log.info("LSTM分数: {}, 最终融合分数: {}", lstmScore, finalScore);
            
            // 2. 获取历史预警数据
            List<MentalHealthWarning> recentWarnings = getRecentWarnings(userId);
            
            // 3. 确定预警等级
            WarningLevel warningLevel = determineWarningLevel(finalScore, recentWarnings);
            
            // 4. 创建预警记录
            MentalHealthWarning warning = MentalHealthWarning.builder()
                .userId(userId)
                .riskScore(finalScore)    // 使用融合后的分数作为风险分数
                .warningLevel(warningLevel)
                .lstmScore(lstmScore)     // 保存反转后的LSTM分数
                .createTime(LocalDateTime.now())
                .build();
            
            log.info("准备保存预警记录: riskScore={}, lstmScore={}, warningLevel={}", 
                finalScore, lstmScore, warningLevel);
            
            warningMapper.insert(warning);
            return warning;
        } catch (Exception e) {
            log.error("生成预警记录失败: ", e);
            throw e;
        }
    }


    private List<MentalHealthWarning> getRecentWarnings(Long userId) {
        // 获取最近24小时的预警记录
        LocalDateTime oneDayAgo = LocalDateTime.now().minusHours(24);
        return warningMapper.selectList(
            new QueryWrapper<MentalHealthWarning>()
                .eq("user_id", userId)
                .ge("create_time", oneDayAgo)
                .orderByDesc("create_time")
        );
    }

    private WarningLevel determineWarningLevel(BigDecimal riskScore, List<MentalHealthWarning> recentWarnings) {
        double score = riskScore.doubleValue();
        
        // 阈值判断：高分表示高风险
        if (score >= 0.7) return WarningLevel.HIGH;      // 消极/高风险
        if (score >= 0.4) return WarningLevel.MEDIUM;    // 中性/中等风险
        return WarningLevel.LOW;                         // 积极/低风险
    }

    @Override
    public MentalHealthWarning getLatestWarning(Long userId) {
        try {
            return warningMapper.selectOne(
                new QueryWrapper<MentalHealthWarning>()
                    .eq("user_id", userId)
                    .orderByDesc("create_time")
                    .last("LIMIT 1")
            );
        } catch (Exception e) {
            log.error("获取最新预警记录失败: userId={}", userId, e);
            return null;
        }
    }
} 